#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;

//data structure
typedef struct{
	int matricula;
	float nota1;
	float nota2;
	float media;
	int faltas;
}ALUNO;

//global variables
ALUNO* *listSeq = NULL;
int dispo = 0;

//atomic functions
ALUNO* first();
ALUNO* last();
ALUNO* search(int index);
ALUNO* search_by_id(int matricula);

int quant_elem();

int menu();
bool show(ALUNO* st);

//non-atomic functions
int find_position(ALUNO*);

bool insert(ALUNO*);
bool remove(ALUNO*);

//==================================================
//MAIN-CODE

int main(){
	int tam, matricula;
	cout << "How many students are in the class? \t";
	cin >> tam;
	
	*listSeq = new ALUNO[tam];
	
	int choice  = menu();
	switch(choice){
		case 1:
			{
				cout << "Enter with the inscription number:\t ";
				cin >> matricula; 
				show(search_by_id(matricula));
			}
			break;
		case 2:
			{
				for (int i=0; i < dispo ; i++){
					show(listSeq[i]);
					cout << endl;
				}
			}
			break;
		case 3:
			{
				int falta;
				float n1, n2, media;
				cout << "Enter with the inscription number: \t";
				cin >> matricula;
				cout << "Enter with the number of abscenses:\t";
				cin >> falta;
				cout << "Enter with the score 1:\t";
				cin >> n1;
				cout<< "Enter with the score 2:\t";
				cin >> n2;
				media = (2*n1 + 3*n2)/5;
				ALUNO* st = new ALUNO;
				st->faltas = falta;
				st->matricula = matricula;
				st->nota1 = n1;
				st->nota2 = n2;
				st->media = media;
				insert(st);
			}
			break;
		case 4:
			{
				cout << "Enter with the inscription number: \t";
				cin >> matricula;
				remove(search_by_id(matricula));
			}
			break;	

		
		default:
			{
				system("cls");
				menu();
			}
			
	}
	
	
}
//==================================================

//Implementation of the functions

//return the first element
ALUNO* first(){
	if (listSeq) return listSeq[0];
	else return NULL;
}

//return the last element
ALUNO* last(){
	if (listSeq) return listSeq[dispo-1];
	else return NULL;
}

//find some element by the index
ALUNO* search(int index){
	if (index < dispo) return listSeq[index];
	else return NULL;
}

//find by the inscription number

ALUNO* search_by_id(int matricula){
	for (int i = 0; i < (dispo-1); i++){
		if (matricula == listSeq[i]->matricula) return listSeq[i];
	}
	return NULL;
}

//find position-index from a student
int find_position(ALUNO* st){
	for(int i=0; i<(dispo-1); i++){
		if ((st->matricula == listSeq[i]->matricula) && (st->nota1 == listSeq[i]->nota1) && (st->nota2 == listSeq[i]->nota2) && (st->media == listSeq[i]->media) && (st->faltas == listSeq[i]->faltas)){
			return i;
		}
	}
	return -1;
}

//return the quantity of elements of the list

int quant_elem(){
	return dispo-1;
}

//insert an element into the list

bool insert(ALUNO* st){
	int i = 0;
 	while (listSeq[i]->matricula < st->matricula){
 		i++;
 	}
 	for(int j = dispo; j > i; j--){
 		listSeq[j] = listSeq[j-1];
 	}
 	
	listSeq[i]->faltas = st->faltas;
	listSeq[i]->matricula = st->matricula;
	listSeq[i]->nota1 = st->nota1;
	listSeq[i]->nota2 = st->nota2;
	listSeq[i]->media = st->media;
	
	return true;
}

//remove an element from the list

bool remove(ALUNO* st){
	int index = find_position(st);
	for(int i = index; i<(dispo-1); i++){
		listSeq[i] = listSeq[i+1];
	}
	return true;
}

//show some element
bool show(ALUNO* st){
	cout << "Insc. Number: " << st->matricula << endl;
	cout << "Absence: " << st->faltas << endl;
	cout << "Score 1: " << st->nota1 << endl;
	cout << "Score 2: " << st->nota2 << endl;
	cout << "Final Score: " << st->media << endl;
}

//show menu
int menu(){
	int ret;
	system("cls");
	cout << "Select an option into menu..." << endl;
	cout << "1 - Verify student." << endl;
	cout << "2 - Show all students." << endl;
	cout << "3 - Insert student." << endl;
	cout << "4 - Remove student." << endl;
	cout << "5 - Exit." << endl;
	cout << "Choice:\t" << endl;
	cin >> ret;
	return ret;
}

